﻿using Gateway.Common.Models;
using Gateway.Domain.Entities;
using Gateway.IApplication.User;
using Gateway.IApplication.User.Input;
using Gateway.IRepositories;

namespace Gateway.Application;
/// <summary>
/// 
/// </summary>
public class UserApp : IUserApp
{
    private readonly IAppRepository<Gateway.Domain.Entities.User> _repository;
    private readonly IUnitOfWork _unitOfWork;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="repository"></param>
    /// <param name="unitOfWork"></param>
    public UserApp(IAppRepository<User> repository, IUnitOfWork unitOfWork)
    {
        _repository = repository;
        _unitOfWork = unitOfWork;
    }
    /// <summary>
    /// 创建
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> Create(CreateUserInput input)
    {
        var entity = new User(userName: input.UserName, userAvatar: input.UserAvatar,
            departmentId: input.DepartmentId,
            roleIds: input.RoleIds,
            account: input.Account,
            password: input.Password
        );
        await _repository.AddAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Update(UpdateUserInput input)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(input.UserId));
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.Update(userName: input.UserName, userAvatar: input.UserAvatar,
            departmentId: input.DepartmentId,
            roleIds: input.RoleIds,
            account: input.Account);
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 改变名称
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> ChangeName(ChangeUserNameInput input)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(input.UserId));
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.ChangeName(userName: input.UserName);
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 移除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> Remove(string id)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(id));
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.SetDeleted();
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 改变password
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="MyException"></exception>
    public async Task<bool> ChangePassword(ChangePasswordInput input)
    {
        var entity = await _repository.FirstOrDefaultAsync(p => p.Id.Equals(input.UserId));
        if (entity == null)
            throw new MyException(SystemErrorCode.DataIsNotAvailable);
        entity.ChangePassword(input.Password);
        await _repository.UpdateAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
}